/**
 *	websocket服务处理
 *	开发者：雨中磐石
 *	地址：www.rockoa.com
 *	日期：2023-07-19
 */


package com.framerock.server;



import com.framerock.baselib.CLog;
import com.framerock.baselib.Jiami;
import com.framerock.baselib.Json;
import com.framerock.baselib.Rock;
import org.java_websocket.framing.Draft;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Map;


public class HttpWebSocket {

    private HttpClient httpClient;
    private Boolean ISOPEN  = true;
    private int messageXu   = 0;
    private Draft draft; //这是用来编码解码的

    /**
     * 人员标识
     * */
    public String adminid       = ""; //此记录标识

    /**
     * 来源
     * */
    public String from          = ""; //来源

    /**
     * 人员姓名
     * */
    public String sendname      = ""; //姓名

    /**
     * 客户端一些信息
     * */
    //public Request mRequest     = null;

    public HttpWebSocket(HttpClient httpclient)
    {
        httpClient      = httpclient;
        //mRequest        = new Request(httpClient);
        draft           = new Draft();
    }

    /**
     * 握手连接
     **/
    public String getSocketbody()
    {
        String key  = httpClient.getHeader("Sec-WebSocket-Key"),newkey = "";
        String skey = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        if(!Rock.isEmpt(key)) {
            try {
                newkey = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-1")
                        .digest((key+skey).getBytes()));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        String str = "HTTP/1.1 101 Switching Protocols\r\n";
        str+="Upgrade: websocket\r\n";
        str+="Sec-WebSocket-Version: 13\r\n";
        str+="Connection: Upgrade\r\n";
        str+="Sec-WebSocket-Accept: "+newkey+"\r\n\r\n";
        return str;
    }

    /**
     * 开始运行
     * */
    public void startRun()
    {
        while (ISOPEN) {
            if(httpClient.isClose()){
                close();break;
            }
            try { startRuns(); }catch (Exception e){ close();}
        }
    }
    private void startRuns(){
        ByteBuffer buf  = httpClient.getByteBuffer();
        if(buf == null)return;
        messageXu ++ ;
        String bstr = draft.decode(buf);
        if (draft.STATE == Draft.CLOSEST) {
            close();
        }
        if (draft.STATE == Draft.MESSAGE) {
            if(messageXu == 1){
                this.linkSuccess(bstr);
            }else {
                WebSocketClient.message(bstr, this);
            }
        }
    }

    /**
     * 首次链接建立
     * */
    private void linkSuccess(String bstr){
        if(!Rock.isEmpt(bstr)) {
            Map<String, String> da = Json.getJsonObject(bstr);
            this.adminid    = Rock.getMapString(da, "adminid");
            this.from       = Rock.getMapString(da, "from");
            this.sendname   = Rock.getMapString(da, "sendname");
        }
        if(Rock.isEmpt(this.sendname))this.sendname = this.adminid;
        if(Rock.isEmpt(this.adminid) || Rock.isEmpt(this.from)){
            close();
            CLog.error("adminid or from is empty");
        }else {
            WebSocketClient.addClient(this);
        }
    }

    /**
     * 关闭链接
     * */
    public void close()
    {
        ISOPEN      = false;
        httpClient.close();
        if(!Rock.isEmpt(this.adminid) && !Rock.isEmpt(this.from))
            WebSocketClient.close(this);
    }

    /**
     * 发送数据
     * */
    public void send(String str)
    {
        Boolean sbool = httpClient.writeResponse(draft.encode(str));
        if(!sbool)close();
    }

    /**
     * 发送数据
     * @param da Map数据
     * */
    public void send(Map<String,String> da)
    {
        send(Json.getJsonString(da));
    }

    /**
     * 发送json数据
     * @param type 类型
     * @param da 发送数据
     * */
    public void sendData(String type, Map<String,String> da)
    {
        if(da == null)da = Rock.getMap();
        da.put("type", type);
        send(da);
    }

    /**
     * 发送json数据
     * @param type 类型
     * */
    public void sendData(String type)
    {
        sendData(type, null);
    }
}
